package xdu.lz.stage1_basic.chapter5_threadPool;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class SimpleThreadPool {
    //线程数
    private final int size;

    //默认大小
    private static final int DEFAULT_SIZE = 10;

    //线程任务队列
    private final static Queue<Runnable> TASK_QUEUE = new LinkedList<>();

    //管理已经执行的线程
    private final static List<WorkerTask> THREAD_LIST = new ArrayList<>();
    //线程组
    private static final ThreadGroup GROUP = new ThreadGroup("POOL_GROUP");
    private static final String THREAD_PREFIX = "SIMPLE_THREAD_POOL";
    //线程编号
    private static volatile int seq = 0;
    public SimpleThreadPool(){
        this(DEFAULT_SIZE);
    }

    public SimpleThreadPool(int size) {
        this.size = size;
        init();
    }

    //创建线程
    private void init() {
        for (int i = 0; i < size; i++) {
            createWorkTask();
        }
    }
    //提交任务
    public void submit(Runnable task){

        synchronized (TASK_QUEUE){
            TASK_QUEUE.offer(task);
            //提交任务后通知
            TASK_QUEUE.notifyAll();
        }
    }

    //创建线程
    private void createWorkTask(){
        WorkerTask task = new WorkerTask(GROUP,THREAD_PREFIX +(seq++));
        //开启线程
        task.start();
        //任务已经被执行
        THREAD_LIST.add(task);
    }

    //线程状态
    private enum TaskState{
        FREE,RUNNING,BLOCK,DEAD
    }
    private static class WorkerTask extends Thread{
        private volatile TaskState taskState = TaskState.FREE;
        public WorkerTask(ThreadGroup group,String name){
            super(group,name);
        }

        @Override
        public void run() {
            while (this.taskState != TaskState.DEAD){
                Runnable runnable;
                synchronized (TASK_QUEUE){
                    while (TASK_QUEUE.isEmpty()){
                        taskState = TaskState.BLOCK;
                        try {
                            //如果任务队列是空则等待，当有任务加入任务队列，会被唤醒
                            TASK_QUEUE.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    runnable = TASK_QUEUE.poll();

                }
                if(runnable != null){
                    taskState = TaskState.RUNNING;
                    runnable.run();
                    taskState = TaskState.FREE;
                }
            }
        }

        public TaskState getTaskState() {
            return taskState;
        }
        public void close(){
            this.taskState = TaskState.DEAD;
        }
    }

    public static void main(String[] args) {
        SimpleThreadPool threadPool = new SimpleThreadPool();
        for (int i = 0; i < 4000; i++) {
            int finalI = i;
            threadPool.submit(()->{
                System.out.println(finalI + "the runnable be serviced by "+Thread.currentThread()+" " +
                        "start.");
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(finalI +"the runnable be serviced by "+Thread.currentThread()+" end.");
            });
            System.out.println("============");
        }
    }
}
